package com.xzxy.xmlg_backend.service;

import com.xzxy.xmlg_backend.entity.Announcements;
import org.springframework.beans.factory.annotation.Autowired;
import com.xzxy.xmlg_backend.service.WebSocketService;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;

/**
 * 公告定时发布服务
 * @author 周毅盛
 * @since 2025-06-16
 */
@Service
public class AnnouncementScheduleService {

    @Autowired
    private WebSocketService webSocketService;

    @Autowired
    private TaskScheduler taskScheduler;

    @Autowired
    private IAnnouncementsService announcementsService;

    // 存储定时任务的映射关系
    private final ConcurrentHashMap<Integer, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();

    /**
     * 创建定时发布任务
     * @param announcementId 公告ID
     * @param publishTime 发布时间
     */
    public void scheduleAnnouncement(Integer announcementId, LocalDateTime publishTime) {
        // 如果已存在该公告的定时任务，先取消
        cancelScheduledAnnouncement(announcementId);

        // 将LocalDateTime转换为Date，使用Asia/Shanghai时区确保时间一致性
        Date publishDate = Date.from(publishTime.atZone(ZoneId.of("Asia/Shanghai")).toInstant());
        
        // 添加调试日志
        System.out.println("创建定时任务 - 公告ID: " + announcementId + ", 发布时间: " + publishTime + ", 转换后时间: " + publishDate);

        // 创建定时任务
        ScheduledFuture<?> scheduledTask = taskScheduler.schedule(
            () -> publishAnnouncement(announcementId),
            publishDate
        );

        // 存储任务引用
        scheduledTasks.put(announcementId, scheduledTask);
    }

    /**
     * 取消定时发布任务
     * @param announcementId 公告ID
     */
    public void cancelScheduledAnnouncement(Integer announcementId) {
        ScheduledFuture<?> scheduledTask = scheduledTasks.get(announcementId);
        if (scheduledTask != null && !scheduledTask.isDone()) {
            scheduledTask.cancel(false);
        }
        scheduledTasks.remove(announcementId);
    }

    /**
     * 执行公告发布
     * @param announcementId 公告ID
     */
    private void publishAnnouncement(Integer announcementId) {
        try {
            System.out.println("开始执行定时发布任务 - 公告ID: " + announcementId + ", 当前时间: " + LocalDateTime.now());
            
            Announcements announcement = announcementsService.getById(announcementId);
            if (announcement != null) {
                System.out.println("找到公告 - ID: " + announcementId + ", 当前状态: " + announcement.getPublishStatus());
                
                if ("暂存".equals(announcement.getPublishStatus())) {
                    announcement.setPublishStatus("已发布");
                    announcement.setUpdatedAt(LocalDateTime.now());
                    boolean updated = announcementsService.updateById(announcement);
                    
                    if (updated) {
                        // 发布成功后从任务映射中移除
                        scheduledTasks.remove(announcementId);
                        webSocketService.sendNotification("定时公告发布", announcement.getTitle(), "info");
                        
                        System.out.println("公告ID: " + announcementId + " 已自动发布成功");
                    } else {
                        System.err.println("公告ID: " + announcementId + " 更新数据库失败");
                    }
                } else {
                    System.out.println("公告ID: " + announcementId + " 状态不是暂存，跳过发布");
                }
            } else {
                System.err.println("未找到公告ID: " + announcementId);
            }
        } catch (Exception e) {
            System.err.println("公告自动发布失败，公告ID: " + announcementId + ", 错误: " + e.getMessage());
            e.printStackTrace();
        }
    }

    /**
     * 获取当前所有定时任务数量
     * @return 任务数量
     */
    public int getScheduledTaskCount() {
        return scheduledTasks.size();
    }

    /**
     * 检查指定公告是否有定时任务
     * @param announcementId 公告ID
     * @return 是否存在定时任务
     */
    public boolean hasScheduledTask(Integer announcementId) {
        ScheduledFuture<?> task = scheduledTasks.get(announcementId);
        return task != null && !task.isDone();
    }


}